from flask import redirect, url_for, flash, render_template, request, Blueprint
from flask_login import login_user, logout_user, login_required, current_user
from models import db, User
import logging
from utils.cache import cache_user_session, get_cached_user_session, delete_cache

logger = logging.getLogger(__name__)

# 创建认证蓝图，处理用户注册、登录和登出功能
auth = Blueprint('auth', __name__)


@auth.route('/register', methods=['GET', 'POST'])
def register_route():
    """用户注册处理"""
    # 已登录用户重定向到手势识别页面
    if current_user.is_authenticated:
        return redirect(url_for('gesture.recognition'))

    if request.method == 'POST':
        try:
            # 获取表单数据
            username = request.form.get('username')
            password = request.form.get('password')
            confirm_password = request.form.get('confirm_password')
            logger.info(f"注册尝试 - 用户名: {username}")

            # 验证表单完整性
            if not username or not password:
                flash('用户名和密码不能为空')
                return render_template('register.html')

            # 验证密码一致性
            if password != confirm_password:
                flash('两次输入的密码不一致')
                return render_template('register.html')

            # 检查用户名是否已存在
            if User.query.filter_by(username=username).first():
                flash('用户名已存在')
                return render_template('register.html')

            # 创建新用户并设置密码（已加密存储）
            new_user = User(username=username)
            new_user.set_password(password)

            # 数据库操作：添加并提交新用户
            try:
                db.session.add(new_user)
                db.session.commit()
                logger.info(f"新用户注册成功: {username}")
                flash('注册成功，请登录')
                return redirect(url_for('auth.login_route'))
            except Exception as e:
                db.session.rollback()  # 回滚事务确保数据一致性
                logger.error(f"注册失败: {str(e)}")
                flash('注册失败，请稍后重试')
                return render_template('register.html')

        except Exception as e:
            logger.error(f"注册过程中发生错误: {str(e)}")
            flash('注册失败，请稍后重试')
            return render_template('register.html')

    return render_template('register.html')


@auth.route('/login', methods=['GET', 'POST'])
def login_route():
    """用户登录处理 - 支持缓存加速"""
    # 已登录用户重定向到手势识别页面
    if current_user.is_authenticated:
        return redirect(url_for('gesture.recognition'))

    if request.method == 'POST':
        try:
            username = request.form.get('username')
            password = request.form.get('password')

            logger.info(f"登录尝试 - 用户名: {username}")

            # 验证表单完整性
            if not username or not password:
                flash('请输入用户名和密码')
                return render_template('login.html')

            # 优先从 Redis 缓存获取用户会话（提升性能）
            cached_session = get_cached_user_session(username)
            if cached_session:
                user = User.query.get(cached_session.get('user_id'))
                if user and user.check_password(password):
                    login_user(user, remember=True)  # 启用记住登录状态功能
                    logger.info(f"用户 {username} 从缓存登录成功")
                    # 处理重定向逻辑（安全过滤防止开放重定向）
                    next_page = request.args.get('next')
                    if not next_page or not next_page.startswith('/'):
                        next_page = url_for('gesture.recognition')
                    return redirect(next_page)

            # 缓存未命中时从数据库验证
            user = User.query.filter_by(username=username).first()
            if user and user.check_password(password):
                login_user(user, remember=True)
                # 缓存用户会话信息（包含用户ID、用户名和角色）
                session_data = {
                    'user_id': user.id,
                    'username': user.username,
                    'role': user.role
                }
                cache_user_session(username, session_data)
                logger.info(f"用户 {username} 登录成功")

                # 安全的重定向处理（防止开放重定向漏洞）
                next_page = request.args.get('next')
                if not next_page or not next_page.startswith('/'):
                    next_page = url_for('gesture.recognition')
                return redirect(next_page)
            else:
                logger.warning(f"登录失败 - 用户名: {username}")
                flash('用户名或密码错误')
                return render_template('login.html')

        except Exception as e:
            logger.error(f"登录过程中发生错误: {str(e)}")
            flash('登录失败，请稍后重试')
            return render_template('login.html')

    return render_template('login.html')


@auth.route('/logout')
@login_required
def logout_route():
    """用户登出处理"""
    # 清除 Redis 中的用户会话缓存
    delete_cache(f'user_session:{current_user.username}')
    # 登出用户（Flask-Login 管理会话）
    logout_user()
    flash('您已成功退出登录')
    return redirect(url_for('auth.login_route'))